<template>
  <a-progress
    :percent="percentage"
    v-bind="$attrs"
    v-on="$listeners"
    :showInfo="false"
    :format="format"
    :key="reRenderNum"></a-progress>
</template>
<script>
export default {
  name: 'ProgressBar',
  props: {},
  data () {
    return {
      status: 0,
      speed: 200,
      minimum: 0.08,
      reRenderNum: 1, // 避免 status由 1-> 0 时，导致进度条倒退。这里直接重新渲染
      resetStatus: true // 避免 status 赋值为 0 时，直接改变进度条样式，需等待再次start进度条才会置空
    }
  },
  computed: {
    percentage () {
      return this.status * 100
    }
  },
  methods: {
    format (e) {
      const num = Number(this.status.toFixed(2))
      return `${parseFloat((num * 100).toPrecision(12))}%`
    },
    // 外部调用使用,当无需使用假的进度条，直接设置 百分比
    setStatus (n) {
      this.status = n
    },
    // 外部调用使用
    start () {
      if (this.resetStatus) {
        this.status = 0
        this.resetStatus = false
        this.reRenderNum++
        this.progress(0)
      }
      const that = this
      const work = function () {
        setTimeout(function () {
          if (that.resetStatus) return
          that.mockIncrease()
          work()
        }, that.speed)
      }

      work()
    },
    // 外部调用使用
    done (force) {
      if (force || this.status) {
        this.mockIncrease(0.3 + 0.5 * Math.random())
        this.progress(1)
      }
    },
    // 向外部发送假的进度
    progress (n) {
      this.status = this.clamp(n, this.minimum, 1)
      // 当 status 为 1 时，进度条停止
      if (this.status === 1) {
        this.resetStatus = true
      }
      this.$emit('progress', n)
    },
    mockIncrease (amount) {
      let n = this.status
      // 如果直接调用 mockIncrease，那么会初始化 start
      if (!n) {
        this.start()
      } else if (n > 1) {
        return
      } else {
        if (typeof amount !== 'number') {
          if (n >= 0 && n < 0.2) {
            amount = 0.1
          } else if (n >= 0.2 && n < 0.5) {
            amount = 0.04
          } else if (n >= 0.5 && n < 0.8) {
            amount = 0.02
          } else if (n >= 0.8 && n < 0.99) {
            amount = 0.005
          } else {
            amount = 0
          }
        }
      }

      n = this.clamp(n + amount, 0, 0.994)
      this.progress(n)
    },
    // 保持进度 n 处于指定的状态（不会过小，也不会超出一定范围）
    clamp (n, min, max) {
      if (n < min) return min
      if (n > max) return max
      return n
    }
  }
}
</script>
